﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI;
using System.ComponentModel;
using System.Drawing.Design;
using TA.JSON;

namespace TA.Turbo.Controls
{
	/// <summary>
	/// A menu item rendered as part of the <see cref="Menu"/> control.
	/// </summary>
	[ParseChildren(true, "Items")]
	public class MenuItem : StyledLabelElement, IJsonSerializable, IJsonDeserializable
	{
		#region PUBLIC
		#region INIT
		/// <summary>
		/// Ctor.
		/// </summary>
		public MenuItem()
		{
			this.DDOrientation = System.Web.UI.WebControls.Orientation.Vertical;
			this._items._owner = this;
		}
		#endregion
		#region PROPS
		/// <summary>
		/// Specifies what action is performed when this menu item is clicked.
		/// </summary>
		public MenuItemActionType Action { get; set; }
		/// <summary>
		/// Specifies the HREF if <see cref="Action"/> is <see cref="MenuItemActionType.HyperLink"/>.
		/// </summary>
		public string Href { get; set; }
		/// <summary>
		/// Gets the collection of sub-items.
		/// </summary>
		[PersistenceMode(PersistenceMode.InnerDefaultProperty)]
		public MenuItemCollection Items { get { return this._items; } }
		/// <summary>
		/// The orientation of the drop down menu which is opened by this menu item.
		/// </summary>
		public System.Web.UI.WebControls.Orientation DDOrientation { get; set; }
		/// <summary>
		/// The position of the drop down menu which is opened by this menu item.
		/// </summary>
		public DropDownPosition DDPosition { get; set; }
		/// <summary>
		/// The mode in which the drop down menu for this menu item is opened.
		/// </summary>
		public DropDownTrigger? DDTrigger { get; set; }
		#endregion
		#region EVENTS
		/// <summary>
		/// Raised when this menu item is clicked and <see cref="Action"/> is <see cref="MenuItemActionType.Event"/>.
		/// </summary>
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
		[PersistenceMode(PersistenceMode.InnerProperty)]
		public ServerEvent<EventArgs> Click { get { return this._click; } }
		#endregion
		#endregion
		#region INTERNAL
		#region VARS
		internal MenuItemCollection _owner;
		internal MenuItemCollection _items = new MenuItemCollection();
		internal ServerEvent<EventArgs> _click = new ServerEvent<EventArgs>();
		internal string _argument;
		#endregion
		#region PROPS
		internal Menu Owner
		{
			get
			{
				return this._owner.Owner;
			}
		}
		/// <summary>
		/// Gets the orientation of the container menu.
		/// </summary>
		protected System.Web.UI.WebControls.Orientation ParentOrientation
		{
			get
			{
				if (this._owner._owner is Menu)
					return ((Menu)this._owner._owner).Orientation;
				return ((MenuItem)this._owner._owner).DDOrientation;
			}
		}
		#endregion
		#region METHODS
		/// <summary>
		/// Renders this menu item.
		/// </summary>
		/// <param name="writer"></param>
		public override void Render(HtmlTextWriter writer)
		{
			this.RenderBeginTag(writer);

			this.RenderLink(writer);

			if (this._items.Count > 0)
			{
				this.RenderDropDown(writer);
			}

			this.RenderEndTag(writer);
		}
		private void RenderBeginTag(HtmlTextWriter writer)
		{
			StringBuilder sbClasses = new StringBuilder("turbo_menu_mi n");
			if (this._items.Count > 0)
			{
				sbClasses.Append(" dd");
			}
			if (this.ParentOrientation == System.Web.UI.WebControls.Orientation.Horizontal)
			{
				sbClasses.Append(" hor");
			}

			if (sbClasses.Length > 0)
				writer.AddAttribute(HtmlTextWriterAttribute.Class, sbClasses.ToString());
			if (this.DDTrigger != null)
			{
				writer.AddAttribute("t", ((int)this.DDTrigger.Value).ToString());
			}
			writer.RenderBeginTag(HtmlTextWriterTag.Li);
		}
		private void RenderLink(HtmlTextWriter writer)
		{
			switch (this.Action)
			{
				case MenuItemActionType.HyperLink:
					if (!string.IsNullOrEmpty(this.Href))
						writer.AddAttribute(HtmlTextWriterAttribute.Href, this.Owner.ResolveUrl(this.Href));
					break;
				case MenuItemActionType.Event:
					writer.AddAttribute(HtmlTextWriterAttribute.Href, "");
					writer.AddAttribute("Arg", this._argument);
					writer.AddAttribute("PS", this.Click.PostScenario.ClientID);
					writer.AddAttribute("Client", this.Click.GetEventClientScript(null));
					//writer.AddAttribute(HtmlTextWriterAttribute.Onclick,
					//  string.Format("{0}; $(\"{1}\").get_Object().HideAll(); return false;", this._click.GetEventScript(this._argument), this.Owner.ClientID));
					break;
			}
			writer.RenderBeginTag(HtmlTextWriterTag.A);

			base.Render(writer);

			writer.RenderEndTag();
		}
		private void RenderDropDown(HtmlTextWriter writer)
		{
			StringBuilder sbClasses = new StringBuilder("turbo_menu_m");
			if (this.DDOrientation == System.Web.UI.WebControls.Orientation.Horizontal)
				sbClasses.Append(" hor");
			writer.AddAttribute(HtmlTextWriterAttribute.Class, sbClasses.ToString());

			if (ParentOrientation == System.Web.UI.WebControls.Orientation.Horizontal)
			{
				writer.AddStyleAttribute(HtmlTextWriterStyle.Left, "0%");

				if (this.DDPosition == DropDownPosition.After)
					writer.AddStyleAttribute(HtmlTextWriterStyle.Top, "100%");
				else
					writer.AddStyleAttribute("bottom", "0%");
			}
			else
			{
				writer.AddStyleAttribute(HtmlTextWriterStyle.Top, "0%");

				if (this.DDPosition == DropDownPosition.After)
					writer.AddStyleAttribute(HtmlTextWriterStyle.Left, "100%");
				else
					writer.AddStyleAttribute("right", "0%");
			}
			writer.RenderBeginTag(HtmlTextWriterTag.Ul);

			foreach (MenuItem item in this._items)
				item.Render(writer);

			writer.RenderEndTag();
		}
		private void RenderEndTag(HtmlTextWriter writer)
		{
			writer.RenderEndTag();
		}
		#endregion
		#region JSON
		/// <summary>
		/// Gets true if any of the properties were modified.
		/// </summary>
		public override bool IsDirty
		{
			get
			{
				return
					base.IsDirty
					|| this.Action != MenuItemActionType.HyperLink
					|| !string.IsNullOrEmpty(this.Href)
					|| this.Items.Count > 0
					|| this.DDOrientation != System.Web.UI.WebControls.Orientation.Vertical
					|| this.DDPosition != DropDownPosition.After;
			}
		}
		/// <summary>
		/// SerializeContents.
		/// </summary>
		/// <param name="jw"></param>
		public override void SerializeContents(JsonWriter jw)
		{
			base.SerializeContents(jw);

			if (!string.IsNullOrEmpty(this.Href))
			{
				jw.PropertyName("H");
				jw.Value(this.Href);
			}

			if (this.Action != MenuItemActionType.HyperLink)
			{
				jw.PropertyName("A");
				jw.Value(this.Action);
			}

			if (this.Items.Count > 0)
			{
				jw.PropertyName("E");
				this.Items.Serialize(jw);
			}

			if (this.DDOrientation != System.Web.UI.WebControls.Orientation.Vertical)
			{
				jw.PropertyName("O");
				jw.Value(this.DDOrientation);
			}

			if (this.DDPosition != DropDownPosition.After)
			{
				jw.PropertyName("P");
				jw.Value(this.DDPosition);
			}
		}
		/// <summary>
		/// DeserializeContent.
		/// </summary>
		/// <param name="jr"></param>
		/// <param name="propShortName"></param>
		public override void DeserializeContent(IJsonReader jr, string propShortName)
		{
			switch (propShortName)
			{
				case "H": this.Href = (string)jr.Value; break;
				case "A": this.Action = (MenuItemActionType)(long)jr.Value; break;
				case "E":
					this.Items.Clear();
					this.Items.Deserialize(jr);
					break;
				case "O": this.DDOrientation = (System.Web.UI.WebControls.Orientation)(long)jr.Value; break;
				case "P": this.DDPosition = (DropDownPosition)(long)jr.Value; break;
				default: base.DeserializeContent(jr, propShortName); break;
			}
		}

		#endregion
		#endregion
	}
}